home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / wink / source / xmodem.c < prev   
Encoding:
C/C++ Source or Header  |  1991-10-19  |  11.4 KB  |  550 lines

  1.  
  2. #define SOH     '\x01'
  3. #define STX     '\x02'
  4. #define EOT     '\x04'
  5. #define ACK     '\x06'
  6. #define NAK     '\x15'
  7. #define CAN     '\x18'
  8. #define CRC     '\x43'
  9. #define    CR    '\x0D'
  10.  
  11. #define    XM_FILE        0
  12. #define    XM_FSIZE    2
  13. #define    XM_TBLK        3
  14. #define    XM_SSIZE    4
  15. #define    XM_SBLK        5
  16. #define    XM_RSIZE    6
  17. #define    XM_RBLK        7
  18. #define    XM_TMOVR    8
  19. #define    XM_RETRY    9
  20. #define    XM_MSG        10
  21.  
  22. #define    DSP_WAIT    50000
  23.  
  24. static void Send(ch)
  25. int    ch;
  26. {
  27.     unsigned int st;
  28.  
  29.     RSB_send(port,ch,&st);
  30. }
  31. static void Send_str(arg,n)
  32. UCHAR    *arg;
  33. int    n;
  34. {
  35.     unsigned int st;
  36.  
  37.     while ( n-- > 0 )
  38.     RSB_send(port,(int)*(arg++),&st);
  39. }
  40. static int Recive()
  41. {
  42.     int    i,ch;
  43.     unsigned int st;
  44. /*
  45.     for ( i = 0 ; RSB_receive(port,&ch,&st) != 0 ; ) {
  46.     if ( ++i > 20000 )
  47.         return ERR;
  48.     }
  49. */
  50.     if ( RSB_receive(port,&ch,&st) != 0 )
  51.     return ERR;
  52.     else 
  53.         return (ch & 0xFF);
  54. }
  55. static int  Recive_str(arg,n)
  56. UCHAR    *arg;
  57. int    n;
  58. {
  59.     int        ch;
  60.  
  61.     while ( n-- > 0 ) {
  62.         if ( (ch = Recive()) == ERR )
  63.         return ERR;
  64.     *(arg++) = ch;
  65.     }
  66.     return FALSE;
  67. }
  68. static int Send_blk(fp,bk)
  69. FILE    *fp;
  70. int     bk;
  71. {
  72.     int     i,j;
  73.     UCHAR   head[3];
  74.     UCHAR   *p,tmp[128];
  75.  
  76.     head[0]=SOH;
  77.     head[1]=bk;
  78.     head[2]=255-bk;
  79.  
  80.     if ( (i=fread(tmp,1,128,fp)) <= 0 ) {
  81.     Send(EOT);
  82.         return ERR;
  83.     }
  84.  
  85.     for ( p=tmp+i ; i < 128 ; i++ )
  86.         *(p++)='\0';
  87.     for ( j = i = 0 ; i < 128 ; i++,j &= 0xff )
  88.         j += tmp[i];
  89.  
  90.     Send_str(head,3);
  91.     Send_str(tmp,128);
  92.     Send(j);
  93.  
  94.     return FALSE;
  95. }
  96. /*************************************************
  97.    <<< X-Modem UpLoad Abort Hit ESC Key >>>
  98.  
  99. File Name    A:WINK.EXP
  100. File Size    xxxx        Total Block  xxxx
  101. Send Size    xxxx        Send Block   xxxx
  102. Recive Size  xxxx        Recive Block xxxx
  103. Time Over    xxxx        ReTry Count  xxxx
  104. Message      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  105.  
  106. 012345678901234567890123456789012345678901234567890
  107. ***************************************************/
  108. void    Xmd_wind(md,file)
  109. char    *md,*file;
  110. {
  111.     int    i;
  112.     long   l;
  113.     char   tmp[160];
  114.     static char *menu[]={
  115.     "File Name",    "",
  116.     "File Size",    "Total Block",
  117.     "Send Size",    "Send Block",
  118.     "Recive Size",    "Recive Block",
  119.     "Time Over",    "ReTry Count",
  120.     "Message",
  121.     NULL
  122.     };
  123.  
  124.     Dmy_form(tmp,50,0x98,0x95,0x99); 
  125.     wrtstr(tmp,15,7,0x05);
  126.  
  127.     Dmy_form(tmp,50,0x96,0x20,0x96); 
  128.     for ( i = 0 ; i < 9 ; i++ )
  129.         wrtstr(tmp,15,8+i,0x05);
  130.  
  131.     Dmy_form(tmp,50,0x9A,0x95,0x9B); 
  132.     wrtstr(tmp,15,17,0x05);
  133.  
  134.     sprintf(tmp,"<<< X-Modem %s Abort Hit ESC Key >>>",md);
  135.     wrtstr(tmp,20,8,0x01);
  136.  
  137.     for ( i = 0 ; menu[i] != NULL ; i++ )
  138.     wrtstr(menu[i],17 + (i % 2) * 28,10 + i / 2,0x05);
  139.  
  140.     wrtstr(file,30,10,0x05);
  141. }
  142. void    Xmd_msg(msg)
  143. char    *msg;
  144. {
  145.     wrtstr(msg,30,15,0x05);
  146. }
  147. void    Xmd_val(no,val)
  148. int    no;
  149. long    val;
  150. {
  151.     char    tmp[40];
  152.  
  153.     sprintf(tmp,"%ld",val);
  154.     wrtstr(tmp,30 + (no % 2) * 28,10 + no / 2,0x05);
  155. }
  156. void    Up_Xmodem(file)
  157. char    *file;
  158. {
  159.     int     i,ch,bk,nk,ef;
  160.     unsigned int ec;
  161.     FILE    *fp;
  162.     long    size;
  163.     char    tmp[80];
  164.  
  165.     Xmd_wind("UpLoad",file);
  166.     if ( (fp = fopen(file,"rb")) == NULL ) {
  167.     Xmd_msg("File Not Found");
  168.     Soft_Timer(DSP_WAIT);
  169.     return;
  170.     }
  171.     fseek(fp,0L,2);
  172.     size = (long)ftell(fp);
  173.     fseek(fp,0L,0);
  174.     Xmd_val(XM_FSIZE,size);
  175.     Xmd_val(XM_TBLK,(size + 127) / 128);
  176.  
  177.     for ( bk = 1, nk = 0, ef = FALSE, size = 0 ; ; ) {
  178.     if ( kbhit() != 0 ) {
  179.         ch = Get_key(&ec);
  180.         if ( ch == 0x1B || ec == 0x7200 ) {
  181.         Xmd_msg("Abort Xmodem Upload !!");
  182.             Send(CAN);
  183.         Soft_Timer(DSP_WAIT);
  184.         break;
  185.         }
  186.     }
  187.     for ( i = 0 ; i < 5 ; i++ ) {
  188.         if ( (ch = Recive()) != ERR ) 
  189.         break;
  190.         Xmd_val(XM_TMOVR,i);
  191.     }
  192.     if ( i >= 5 ) {
  193.         Xmd_msg("Time Over Aobrt !!");
  194.         Soft_Timer(DSP_WAIT);
  195.         break;
  196.     }
  197.     if ( ch == ACK ) {
  198.         size += 128; nk = 0; bk++;
  199.         if ( ef != FALSE ) {
  200.         Xmd_msg("End of Upload !!");
  201.         break;
  202.         }
  203.         if ( Send_blk(fp,bk) != FALSE )
  204.         ef = TRUE;
  205.         else {
  206.         Xmd_val(XM_SSIZE,size + 128);
  207.         Xmd_val(XM_SBLK,bk);
  208.         }
  209.     } else if ( ch == NAK ) {
  210.         if ( nk++ > 0 )
  211.         Xmd_val(XM_RETRY,nk);
  212.         fseek(fp,size,SEEK_SET);
  213.         if ( Send_blk(fp,bk) != FALSE )
  214.         ef = TRUE;
  215.         else {
  216.         Xmd_val(XM_SSIZE,size + 128);
  217.         Xmd_val(XM_SBLK,bk);
  218.         }
  219.     } else if ( ch == CAN ) {
  220.             Xmd_msg("Recive Cansel Code !!");
  221.         Soft_Timer(DSP_WAIT);
  222.             break;
  223.         }
  224.         if ( nk >= 5 ) {
  225.             Xmd_msg("ReTry Over Abort !!");
  226.         Send(CAN);
  227.         Soft_Timer(DSP_WAIT);
  228.         break;
  229.     }
  230.     }
  231.     fclose(fp);
  232. }
  233. void    Down_Xmodem(file)
  234. char    *file;
  235. {
  236.     int     i,j,ch,bk,nk,ef;
  237.     unsigned int ec;
  238.     long    size;
  239.     FILE    *fp;
  240.     UCHAR   tmp[128];
  241.  
  242.     Xmd_wind("DownLoad",file);
  243.     if ( (fp = fopen(file,"wb")) == NULL ) {
  244.     wrtstr("ファイルが作成出来ません",30,1,0x12);
  245.     return;
  246.     }
  247.     for ( ef = TRUE,bk = 1,size = 0,nk = 0 ; ; ) {
  248.     if ( kbhit() != 0 ) {
  249.         ch = Get_key(&ec);
  250.         if ( ch == 0x1B || ec == 0x7200 ) {
  251.         Xmd_msg("Abort Xmodem Upload !!");
  252.             Send(CAN);
  253.         Soft_Timer(DSP_WAIT);
  254.         break;
  255.         }
  256.     }
  257.     for ( i = 0 ; i < 5 ; i++ ) {
  258.         if ( ef == FALSE )
  259.         Send(ACK);
  260.         else if ( Flaing == FALSE )
  261.         Send(NAK);
  262.         else {
  263.         Send(NAK); Send(ACK);
  264.         }
  265.         if ( (ch = Recive()) != ERR ) 
  266.         break;
  267.         Xmd_val(XM_TMOVR,i);
  268.     }
  269.     if ( i >= 5 ) {
  270.         Xmd_msg("Time Over Aobrt !!");
  271.         Soft_Timer(DSP_WAIT);
  272.         break;
  273.     }
  274.     if ( ch == EOT ) {
  275.         Xmd_msg("End of DownLoad !!");
  276.         if ( Flaing == FALSE )
  277.         Send(ACK);
  278.         break;
  279.     } else if ( ch == CAN ) {
  280.             Xmd_msg("Recive Cansel Code !!");
  281.         Soft_Timer(DSP_WAIT);
  282.             break;
  283.         } else if ( ch == SOH ) {
  284.             if ( Recive() != (bk & 0xff) )
  285.         goto ERROR;
  286.             if ( (255 - Recive()) != (bk & 0xff) )
  287.         goto ERROR;
  288.         if ( Recive_str(tmp,128) != FALSE )
  289.         goto ERROR;
  290.         for ( j = i = 0 ; i < 128 ; i++,j &= 0xff )
  291.         j += tmp[i];
  292.         if ( Recive() != j )
  293.         goto ERROR;
  294.  
  295.         fwrite(tmp,1,128,fp);
  296.         size += 128;
  297.         Xmd_val(XM_RSIZE,size);
  298.         Xmd_val(XM_RBLK,bk);
  299.         ef = FALSE;
  300.         nk = 0;
  301.         bk++;
  302.         continue;
  303.     }
  304. ERROR:  Recive_str(tmp,128);    /* Dummy */
  305.     ef = TRUE;
  306.     Xmd_val(XM_RETRY,++nk);
  307.         if ( nk >= 5 ) {
  308.             Xmd_msg("ReTry Over Abort !!");
  309.         Send(CAN);
  310.         Soft_Timer(DSP_WAIT);
  311.         break;
  312.     }
  313.     }
  314.     fclose(fp);
  315. }
  316. /**************************
  317.     Auto Login
  318. **************************/
  319. int    htob(ch)
  320. int     ch;
  321. {
  322.     int     i=0;
  323.  
  324.     if ( ch >= 'a' && ch <= 'z' )
  325.     ch &= 0xDF;
  326.     if ( '0' <= ch && ch <= '9' )
  327.         i = ch - '0';
  328.     else if ( 'A' <= ch && ch <= 'F' )
  329.         i = ch - 'A' + 10;
  330.     return i;
  331. }
  332. int    Wait_recive(tick)
  333. int    tick;
  334. {
  335.     int     len,ch;
  336.     unsigned int st;
  337.     long    l,s;
  338.  
  339.     gtime(&l); l += tick;
  340.     do {
  341.     RSB_read(port,&len);
  342.         if ( len > 0 ) {
  343.         RSB_receive(port,&ch,&st);
  344.         BakPut(ch); Dsp_vram(cvram);
  345.         return ch;
  346.     }
  347.     gtime(&s);
  348.     } while ( kbhit() == 0 && s < l );
  349.     return ERR;
  350. }
  351. void    RS_Sleep(tick)
  352. int    tick;
  353. {
  354.     int     len,ch;
  355.     unsigned int st;
  356.     long    l,s;
  357.  
  358.     gtime(&l); l += tick;
  359.     do {
  360.     RSB_read(port,&len);
  361.         if ( len > 0 ) {
  362.         while ( len-- > 0 ) {
  363.             RSB_receive(port,&ch,&st);
  364.             BakPut(ch);
  365.         }
  366.         Dsp_vram(cvram);
  367.     }
  368.     gtime(&s);
  369.     } while ( kbhit() == 0 && s < l );
  370. }
  371. int    cmpstr(arg)
  372. char    *arg;
  373. {
  374.     int     ch,wt;
  375.     register char    *p;
  376.  
  377.     for ( p = arg,wt = 0 ; isdigit(*p) ; p++ )
  378.     wt = wt * 10 + *p - '0';
  379.     if ( *p == ',' && wt > 0 )
  380.     arg = p + 1;
  381.     else
  382.     wt = 30;
  383.  
  384.     for ( p=arg ; *p != ']' ; ) {
  385.         if ( (ch=Wait_recive(wt)) == ERR )
  386.             return ERR;
  387.         if ( ch == (*p & 0xff) )
  388.             p++;
  389.         else
  390.             p=arg;
  391.     }
  392.     return FALSE;
  393. }
  394. int    cmpmac(arg)
  395. char    *arg;
  396. {
  397.     int     ch,wt;
  398.     register char    *p;
  399.  
  400.     for ( p = arg,wt = 0 ; isdigit(*p) ; p++ )
  401.     wt = wt * 10 + *p - '0';
  402.     if ( *p == ',' && wt > 0 )
  403.     arg = p + 1;
  404.     else
  405.     wt = 5;
  406.  
  407.     for ( p=arg ; *p != '}' ; ) {
  408.         if ( (ch=Wait_recive(wt)) == ERR )
  409.             return ERR;
  410.         if ( ch == (*p & 0xff) )
  411.             p++;
  412.         else
  413.             p=arg;
  414.     }
  415.     return FALSE;
  416. }
  417. int    runlog(arg)
  418. register char    *arg;
  419. {
  420.     int     ch;
  421.     char    *p;
  422.     char    *adr=NULL;
  423.  
  424.     for ( ; *arg != '\0' ; arg++ ) {
  425.         switch(*arg) {
  426.             case '<':
  427.                 Send(CR);
  428.                 break;
  429.             case '>':
  430.                 while ( (ch=Wait_recive(30)) != CR ) {
  431.             if ( ch == ERR )
  432.             return ERR;
  433.                     if ( kbhit() != 0 )
  434.                         return TRUE;
  435.                 }
  436.                 break;
  437.             case '$':
  438.                 Send( htob(*(++arg)) << 4 | htob(*(++arg)) );
  439.                 break;
  440.             case '\\':
  441.                 Send(*(++arg));
  442.                 break;
  443.             case '*':
  444.                 RS_Sleep(2);
  445.                 break;
  446.             case '?':
  447.         adr = arg;
  448.         break;
  449.             case '@':
  450.         adr = NULL;
  451.         break;
  452.             case '[':
  453.                 if ( cmpstr(++arg) != FALSE )
  454.                     return ERR;
  455.                 while ( *arg != ']' ) arg++;
  456.                 break;
  457.             case '{':
  458.         if ( adr == NULL ) {
  459.                     for ( p = arg ; *p != '?' && *p != '\0' ; p++ )
  460.             if ( *p == '?' )
  461.                 adr = p;
  462.             else
  463.                 return ERR;
  464.         }
  465.                 if ( cmpmac(++arg) != FALSE ) {
  466.             if ( kbhit() != 0 )
  467.             return ERR;
  468.             arg = adr;
  469.         } else
  470.                     while ( *arg != '}' ) arg++;
  471.                 break;
  472.             default:
  473.                 Send(*arg);
  474.                 break;
  475.         }
  476.         if ( kbhit() != 0 )
  477.             return TRUE;
  478.     }
  479.     return FALSE;
  480. }
  481. char    *Auto_menu[21]={ NULL };
  482. char    *Auto_para[21];
  483.  
  484. void    Auto_log()
  485. {
  486.     static int  no=ERR;
  487.  
  488.     if ( Auto_menu[0] == NULL )
  489.     goto ENDOF;
  490.  
  491.     if ( Sel_menu(Auto_menu,20,2,&no) != FALSE )
  492.     goto ENDOF;
  493.  
  494.     wrtstr(SPCSTR,30,1,0x1F);
  495.     if ( runlog(Auto_para[no]) == ERR )
  496.     wrtstr("オ-トを中断しました",30,1,0x15);
  497.  
  498. ENDOF:
  499.     Dsp_vram(cvram);
  500.     Dsp_free();
  501. }
  502.  
  503. char    *Auto_log_file="WINK.DEF";
  504.  
  505. void    Auto_log_init()
  506. {
  507.     int     i,mx=0;
  508.     FILE    *fp;
  509.     char    *p,*s,*n;
  510.     char    tmp[256];
  511.     char    work[4096];
  512.  
  513.     if ( (p = getenv("WINKAUTO")) != NULL )
  514.     Auto_log_file = p;
  515.  
  516.     if ( (fp = fopen(Auto_log_file,"r")) == NULL )
  517.     return;
  518.  
  519.     while ( (p = fgets(tmp,256,fp)) != NULL ) {
  520.     while ( isspace(*p) ) p++;
  521.     while ( p != NULL && *p == '#' ) {
  522.         for ( s = ++p ; *s != '\n' && *s != '\0' ; s++ );
  523.         *s = '\0';
  524.         if ( (n = Auto_menu[mx] = (char *)malloc(22)) == NULL )
  525.         goto ENDOF;
  526.         for ( i = 0 ; i < 20 && *p != '\0' ; i++ )
  527.         *(n++) = *(p++);
  528.         for ( ; i < 20 ; i++ )
  529.         *(n++) = ' ';
  530.         *n = '\0';
  531.         for ( s = work ; (p = fgets(tmp,256,fp)) != NULL ; ) {
  532.         while ( isspace(*p) ) p++;
  533.         if ( *p == '#' )
  534.             break;
  535.         while ( *p != '\n' && *p != '\0' )
  536.             *(s++) = *(p++);
  537.         }
  538.         *s = '\0';
  539.         if ( (Auto_para[mx] = (char *)malloc(strlen(work)+1)) == NULL )
  540.         goto ENDOF;
  541.         strcpy(Auto_para[mx],work);
  542.         if ( ++mx >= 20 )
  543.             goto ENDOF;
  544.     }
  545.     }
  546. ENDOF:
  547.     fclose(fp);
  548.     Auto_menu[mx] = NULL;
  549. }
  550.